package common;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Frame;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Map;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

import org.math.plot.utils.Array;
import org.uncommons.watchmaker.framework.EvaluatedCandidate;

import fitness.AmplyFitness;
import fitness.Fitness;
import fitness.MathFitness;
import fitness.SquareFitness;
import optimizers.commons.Parameter;
import optimizers.commons.RunConfig;
import optimizers.ganeat.Individual;
import optimizers.ganeat.math.IndividualMath;
import optimizers.ganeat.square.GASquare;
import optimizers.ganeat.square.IndividualSquare;
import runconfiguration.SquareConfiguration;
import visualization.GraphDisplayer;

public class Static {
	public static DecimalFormat df2 = new DecimalFormat("#.##");
	public static DecimalFormat df4 = new DecimalFormat("#.####");
	public static DecimalFormat df8 = new DecimalFormat("#.########");

	public static Map<String, Integer> nameToInt = new HashMap<String, Integer>();
	public static Map<Integer, String> intToName = new HashMap<Integer, String>();

	public static HashMap<String, String> prototypes = new HashMap<String, String>();
	public static RunStarter[] runs;

	public static Frame frame;

	public static double[] seqKForDE = new double[] { 11.04, 52.2, 53.8, 54.05,
		86.59, 105.75, 150.4, 169.4, 242.08, 255.49, 261.65, 396.5, 470.6,
		580.24, 618.25 };
	
	public static double[] seqK = new double[] { 11.04, 52.2, 53.8, 54.05,
			86.59, 105.75, 150.4, 169.4, 242.08, 255.49, 261.65, 396.5, 470.6,
			580.24, 618.25 };
	public static String[] seqStr = new String[] { "ACGAGTCGGGA",
			"ACGAGTCGAGT", "TGGAGTCCGTT", "GTGAGTCTGGC", "AGGAGTCCGAA",
			"GCGAGTCGATA", "GTGAGTCCACA", "GAGAGTCTGCA", "GAGAGTCACCA",
			"ACGAGTCGTAA", "AGGAGTCCTTG", "GTGAGTCCCTA", "TCGAGTCAGAT",
			"GTGAGTCACAA", "AGGAGTCGTAT" };
	public static double[][] inhibKm = new double[][] {
			{ 0.0425, 0.0425, 0.0796, 0.0816, 0.0863, 0.0077, 0.0816, 0.1316,
					0.1316, 0.0425, 0.0863, 0.0816, 0.0632, 0.0816, 0.0863 },
			{ 0.3378, 0.3378, 0.3155, 0.2989, 0.7881, 0.0282, 0.2989, 0.4811,
					0.4811, 0.3378, 0.7881, 0.2989, 0.1848, 0.2989, 0.7881 },
			{ 0.2547, 0.2547, 0.2072, 0.196, 0.5176, 0.0185, 0.196, 0.3155,
					0.3155, 0.2547, 0.5176, 0.196, 0.1644, 0.196, 0.5176 },
			{ 0.0355, 0.0355, 0.0721, 0.0355, 0.0721, 0.0033, 0.0355, 0.0572,
					0.0572, 0.0355, 0.0721, 0.0355, 0.0572, 0.0355, 0.0721 },
			{ 0.1644, 0.1644, 0.3076, 0.3155, 0.3335, 0.0298, 0.3155, 0.5086,
					0.5086, 0.1644, 0.3335, 0.3155, 0.244, 0.3155, 0.3335 },
			{ 1.2704, 1.2704, 2.7381, 2.8085, 2.9688, 0.265, 2.8085, 4.5276,
					4.5276, 1.2704, 2.9688, 2.8085, 1.6041, 2.8085, 2.9688 },
			{ 0.196, 0.196, 0.3668, 0.3768, 0.3977, 0.0355, 0.3768, 0.6066,
					0.6066, 0.196, 0.3977, 0.3768, 0.2914, 0.3768, 0.3977 },
			{ 0.1372, 0.1372, 0.2571, 0.2637, 0.2788, 0.0249, 0.2637, 0.4245,
					0.4245, 0.1372, 0.2788, 0.2637, 0.2039, 0.2637, 0.2788 },
			{ 0.196, 0.196, 0.3668, 0.3768, 0.3977, 0.0355, 0.3768, 0.6066,
					0.6066, 0.196, 0.3977, 0.3768, 0.2914, 0.3768, 0.3977 },
			{ 0.7268, 0.7268, 1.8445, 1.8919, 1.9968, 0.1214, 1.8919, 3.0452,
					3.0452, 0.7268, 1.9968, 1.8919, 1.0789, 1.8919, 1.9968 },
			{ 0.3155, 0.3155, 0.3977, 0.3977, 0.6412, 0.0375, 0.3977, 0.6412,
					0.6412, 0.3155, 0.6412, 0.3977, 0.3155, 0.3977, 0.6412 },
			{ 0.5176, 0.5176, 0.9686, 0.9935, 1.0502, 0.0937, 0.9935, 1.6016,
					1.6016, 0.5176, 1.0502, 0.9935, 0.7683, 0.9935, 1.0502 },
			{ 2.8085, 2.8085, 2.2851, 2.1616, 5.7078, 0.2039, 2.1616, 3.4848,
					3.4848, 2.8085, 5.7078, 2.1616, 1.8126, 2.1616, 5.7078 },
			{ 0.7574, 0.7574, 1.4174, 0.8947, 1.5369, 0.1372, 0.8947, 2.3438,
					2.3438, 0.7574, 1.5369, 0.8947, 1.1261, 0.8947, 1.5369 },
			{ 1.6744, 1.6744, 1.8445, 1.7449, 4.6073, 0.112, 1.7449, 2.8085,
					2.8085, 1.6744, 4.6073, 1.7449, 1.0789, 1.7449, 4.6073 } };

	public static Color[] colors = new Color[] { new Color(255, 128, 128),
			new Color(255, 255, 128), new Color(128, 255, 128),
			new Color(0, 255, 128), new Color(128, 255, 255),
			new Color(0, 128, 255), new Color(255, 128, 192),
			new Color(255, 128, 255), new Color(255, 0, 0),
			new Color(255, 255, 0), new Color(128, 255, 0),
			new Color(0, 255, 64), new Color(0, 255, 255),
			new Color(0, 128, 192), new Color(128, 128, 192),
			new Color(255, 0, 255), new Color(128, 64, 64),
			new Color(255, 128, 64), new Color(0, 255, 0),
			new Color(0, 128, 128), new Color(0, 64, 128),
			new Color(128, 128, 255), new Color(128, 0, 64),
			new Color(255, 0, 128), new Color(128, 0, 0),
			new Color(255, 128, 0), new Color(0, 128, 0),
			new Color(0, 128, 64), new Color(0, 0, 255), new Color(0, 0, 160),
			new Color(128, 0, 128), new Color(128, 0, 255),
			new Color(64, 0, 0), new Color(128, 64, 0), new Color(0, 64, 0),
			new Color(0, 64, 64), new Color(0, 0, 128), new Color(0, 0, 64),
			new Color(64, 0, 64), new Color(64, 0, 128),
			new Color(128, 128, 0), new Color(128, 128, 64),
			new Color(128, 128, 128), new Color(64, 128, 128),
			new Color(192, 192, 192), new Color(255, 255, 255) };

	static {
		prototypes.put("Simplest", "Node gens:\r\n"
				+ " a 11.04 20 ACGAGTCGGGA\r\n" + "Connection gens:\r\n"
				+ " 1 a->a true 3.7959\r\n" + "Exo: 0.68182\r\n"
				+ "Pol: 17\r\n" + "Nick: 3");
		prototypes
				.put("Oligator",
						"Node gens:\r\n"
								+ " a 11.04 20 ACGAGTCGGGA\r\nb 52.2 10 ACGAGTCGAGT\r\nIaa 3 0.1\r\n"
								+ "Connection gens:\r\n"
								+ " 1 a->a true 3.7959\r\n 2 a->b true 3.7\r\n 3 b->Iaa true 10\r\n"
								+ "Exo: 0.68182\r\n" + "Pol: 17\r\n"
								+ "Nick: 3");
		prototypes.put("Starting amplify", "Node gens:\r\n"
				+ " a 11.04 1e-9 ACGAGTCGGGA\r\n"
				+ " b 52.2 1e-9 ACGAGTCGAGT\r\n"
				+ " c 470.6 1e-9 TCGAGTCAGAT\r\n" + "Connection gens:\r\n"
				+ " 1 a->a false 3.7959\r\n" + "2 a->c true 10\r\n"
				+ "3 c->b true 10\r\n" + "Exo: 0.68182\r\n" + "Pol: 17\r\n"
				+ "Nick: 3");
		prototypes.put("Starting math", "Node gens:\r\n"
				+ " a 11.04 0 ACGAGTCGGGA\r\n" + " b 52.2 10 ACGAGTCGAGT\r\n"
				+ "Connection gens:\r\n" + " 1 a->a false 3.7959\r\n"
				+ " 2 a->b true 10.1514\r\n" + "Exo: 0.6818\r\n"
				+ "Pol: 17\r\n" + "Nick: 3");
		prototypes.put("Square 1", "Node gens:\r\n"
				+ " a 54.05 0 GTGAGTCTGGC\r\n" + " b 105.75 10 GCGAGTCGATA\r\n"
				+ " f 150.4 10 GTGAGTCCACA\r\n" + " Iab 0.0033 10 null\r\n"
				+ "Connection gens:\r\n" + " 1 a->b true 55.8456\r\n"
				+ " 2 f->Iab true 60\r\n" + " 3 f->f true 7.6809\r\n"
				+ "Exo: 0.6818\r\n" + "Pol: 17\r\n" + "Nick: 3");
		prototypes.put("Square 2", "Node gens:\r\n"
				+ " a 261.65 0 AGGAGTCCTTG\r\n" + " b 396.5 10 GTGAGTCCCTA\r\n"
				+ " d 242.08 10 GAGAGTCACCA\r\n" + " Ibb 0.9935 10 null\r\n"
				+ " Idd 0.6066 10 null\r\n" + "Connection gens:\r\n"
				+ " 1 b->b true 45.8817\r\n" + " 2 d->Ibb true 25.3796\r\n"
				+ " 3 d->d true 42.4382\r\n" + " 4 a->Idd true 44.1227\r\n"
				+ "Exo: 0.6818\r\n" + "Pol: 17\r\n" + "Nick: 3\r\n");
		prototypes.put("Square 3", "Node gens:\r\n"
				+ " a 11.04 0 ACGAGTCGGGA\r\n" + " b 54.05 10 GTGAGTCTGGC\r\n"
				+ " d 150.4 10 GTGAGTCCACA\r\n" 
				+ " Iab 0.0816 10 null\r\n" + "Connection gens:\r\n"
				+ " 1 a->b true 30.9855\r\n" + " 2 d->d true 60\r\n"
				+ " 3 d->Iab true 8.7468\r\n" + " 4 a->d true 42.9979\r\n"
				+ "Exo: 0.6818\r\n" + "Pol: 17\r\n" + "Nick: 3");
		prototypes.put("Square 4", "Node gens:\r\n"
				+ " a 618.25 0 AGGAGTCGTAT\r\n"
				+ " b 580.24 10 GTGAGTCACAA\r\n"
				+ " d 396.5 10 GTGAGTCCCTA\r\n" + " Ibb 0.8947 10 null\r\n"
				+ " Idd 0.9935 10 null\r\n" + "Connection gens:\r\n"
				+ " 1 a->b true 42.8684\r\n" + " 2 b->b true 10.817\r\n"
				+ " 3 d->Ibb true 53.9089\r\n" + " 4 d->d true 48.2199\r\n"
				+ " 5 b->Idd true 43.8604\r\n" + "Exo: 0.6818\r\n"
				+ "Pol: 17\r\n" + "Nick: 3");
		prototypes.put("Square 5", "Node gens:\r\n"
				+ " a 54.05 0 GTGAGTCTGGC\r\n" + " b 11.04 10 ACGAGTCGGGA\r\n"
				+ " d 242.08 10 GAGAGTCACCA\r\n" + " Idd 0.6066 10 null\r\n"
				+ " Iab 0.0355 10 null\r\n" + "Connection gens:\r\n"
				+ " 1 a->b true 20.6567\r\n" + " 2 d->d true 22.7861\r\n"
				+ " 3 b->Idd true 39.767\r\n" + " 4 d->Iab true 54.3313\r\n"
				+ " 5 a->d true 26.2686\r\n" + "Exo: 0.6818\r\n"
				+ "Pol: 17\r\n" + "Nick: 3\r\n");
		prototypes.put("Gaussian 1", "Node gens:\r\n" + 
				" a 11.04 0 ACGAGTCGGGA\r\n" + 
				" b 169.4 10 GAGAGTCTGCA\r\n" + 
				" c 150.4 10 GTGAGTCCACA\r\n" + 
				" Ibb 0.4245 10 null\r\n" + 
				" Icc 0.3768 10 null\r\n" + 
				"Connection gens:\r\n" + 
				" 1 b->b true 56.3196\r\n" + 
				" 2 c->c true 30.3359\r\n" + 
				" 3 a->Ibb true 18.3481\r\n" + 
				" 4 a->Icc true 13.2697\r\n" + 
				" 5 c->Ibb true 40.2323\r\n" + 
				"Exo: 0.6818\r\n" + 
				"Pol: 17\r\n" + 
				"Nick: 3");
		prototypes.put("Gaussian 2", "Node gens:\r\n" + 
				" a 11.04 0 ACGAGTCGGGA\r\n" + 
				" b 242.08 10 GAGAGTCACCA\r\n" + 
				" c 396.5 10 GTGAGTCCCTA\r\n" + 
				" Ibb 0.6066 10 null\r\n" + 
				" Icc 0.9935 10 null\r\n" + 
				"Connection gens:\r\n" + 
				" 1 b->b true 54.2111\r\n" + 
				" 2 c->c true 18.1955\r\n" + 
				" 3 a->Ibb true 17.3427\r\n" + 
				" 4 a->Icc true 28.6728\r\n" + 
				" 5 b->Ibb true 16.9797\r\n" + 
				" 6 c->Ibb true 52.0904\r\n" + 
				"Exo: 0.6818\r\n" + 
				"Pol: 17\r\n" + 
				"Nick: 3");
		prototypes.put("Gaussian 3", "Node gens:\r\n" + 
				" a 11.04 0 ACGAGTCGGGA\r\n" + 
				" b 54.05 10 GTGAGTCTGGC\r\n" + 
				" c 580.24 10 GTGAGTCACAA\r\n" + 
				" Icc 0.8947 10 null\r\n" + 
				" Ibb 0.0355 10 null\r\n" + 
				"Connection gens:\r\n" + 
				" 1 c->c true 30.6799\r\n" + 
				" 2 b->b true 4.2244\r\n" + 
				" 3 a->Icc true 59.998\r\n" + 
				" 4 c->Ibb true 1.5233\r\n" + 
				"Exo: 0.6818\r\n" + 
				"Pol: 17\r\n" + 
				"Nick: 3");
		prototypes.put("Gaussian 4", "Node gens:\r\n" + 
				" a 11.04 0 ACGAGTCGGGA\r\n" + 
				" b 261.65 10 AGGAGTCCTTG\r\n" + 
				" c 255.49 10 ACGAGTCGTAA\r\n" + 
				" d 242.08 10 GAGAGTCACCA\r\n" + 
				" Idd 0.6066 10 null\r\n" + 
				" Iac 0.0425 10 null\r\n" + 
				"Connection gens:\r\n" + 
				" 1 a->c true 54.5535\r\n" + 
				" 2 c->b true 16.7597\r\n" + 
				" 3 d->d true 25\r\n" + 
				" 4 b->Idd true 25\r\n" + 
				" 5 d->Iac true 18.7033\r\n" + 
				"Exo: 0.6818\r\n" + 
				"Pol: 17\r\n" + 
				"Nick: 3");
		prototypes.put("Gaussian 5", "Node gens:\r\n" + 
				" a 11.04 0 ACGAGTCGGGA\r\n" + 
				" b 618.25 10 AGGAGTCGTAT\r\n" + 
				" c 53.8 10 TGGAGTCCGTT\r\n" + 
				" d 580.24 10 GTGAGTCACAA\r\n" + 
				" Ibb 4.6073 10 null\r\n" + 
				" Icc 0.2072 10 null\r\n" + 
				" Idd 0.8947 10 null\r\n" + 
				"Connection gens:\r\n" + 
				" 1 b->b true 22.4516\r\n" + 
				" 2 c->c true 14.0775\r\n" + 
				" 3 d->d true 7.606\r\n" + 
				" 4 a->Ibb true 25\r\n" + 
				" 5 a->Icc true 51.6659\r\n" + 
				" 6 c->Idd true 60\r\n" + 
				"Exo: 0.6818\r\n" + 
				"Pol: 17\r\n" + 
				"Nick: 3");
		prototypes.put("Starting math 2 inputs", "Node gens:\r\n"
				+ " a 11.04 0 ACGAGTCGGGA\r\n" + " b 52.2 0 ACGAGTCGAGT\r\n"
				+ " c 470.6 10 TCGAGTCAGAT\r\n" + "Connection gens:\r\n"
				+ " 1 a->c true 3.7959\r\n" + " 2 b->c true 10.1514\r\n"
				+ "Exo: 0.6818\r\n" + "Pol: 17\r\n" + "Nick: 3");
		prototypes.put("Check math", "Node gens:\r\n" + 
				" a 580.24 0 GTGAGTCACAA\r\n" + 
				" b 169.4 10 GAGAGTCTGCA\r\n" + 
				" c 150.4 10 GTGAGTCCACA\r\n" + 
				" Icc 0.3768 10 null\r\n" + 
				" h 255.49 10 ACGAGTCGTAA\r\n" + 
				" Ibh 0.1372 10 null\r\n" + 
				" i 53.8 10 TGGAGTCCGTT\r\n" + 
				" Ici 0.3668 10 null\r\n" + 
				"Connection gens:\r\n" + 
				" 1 a->a false 3.7959\r\n" + 
				" 2 a->b false 4.7196\r\n" + 
				" 3 b->b false 11.0921\r\n" + 
				" 5 c->c true 12.5546\r\n" + 
				" 6 a->Icc true 17.2443\r\n" + 
				" 21 b->h true 11.0921\r\n" + 
				" 22 h->b true 11.0921\r\n" + 
				" 23 c->Ibh false 19.0921\r\n" + 
				" 24 c->i true 12.6786\r\n" + 
				" 49 i->Ici true 21.3126\r\n" + 
				" 55 i->Ibh true 27.8181\r\n" + 
				" 69 h->Icc true 25\r\n" + 
				"Exo: 0.6818\r\n" + 
				"Pol: 17\r\n" + 
				"Nick: 3");
		prototypes.put("Browse", "Node gens:\r\n"
				+ " a 191.41 20 CTGAGTCGGAT\r\n" + "Connection gens:\r\n"
				+ " 1 a->a true 3.7959\r\n" + "Exo: 0.68182\r\n"
				+ "Pol: 17\r\n" + "Nick: 3");

		runs = new RunStarter[] { new RunAmplify(), new RunSquareOscillation(),
				new RunMath(), new RunFastStrongOscillation(), new RunPulse(),
				new RunFCD() };
	}

	public static String[] getListPrototypes() {
		return (String[]) prototypes.keySet().toArray(new String[0]);
	}

	static {
		for (int i = 0; i < 20; i++) {
			int j = i + 97;
			char c = (char) j;
			String nodeName = Character.toString(c);
			intToName.put(i, nodeName);
			nameToInt.put(nodeName, i);
		}
	}

	public static void main(String[] args) {
		/*
		 * RunConfig config = new RunConfig(); config.inhK = new
		 * Parameter(RunConfig.INHK_OPTIMIZE_NO_PRESET, 0, 0, 0, new double[]
		 * {});
		 * 
		 * IndividualMath indiv1 = new IndividualMath( new HashMap<String,
		 * Integer>(), new HashMap<String, String>(), 0, 0, config,
		 * prototypes.get("Test math")); showPanelIndiv(indiv1, "Prototype 1");
		 * IndividualMath indiv2 = new IndividualMath( new HashMap<String,
		 * Integer>(), new HashMap<String, String>(), 0, 0, config,
		 * prototypes.get("Test math 2")); showPanelIndiv(indiv2,
		 * "Prototype 2"); IndividualMath indiv3 = new IndividualMath( new
		 * HashMap<String, Integer>(), new HashMap<String, String>(), 0, 0,
		 * config, prototypes.get("Test math 3")); showPanelIndiv(indiv3,
		 * "Prototype 3"); IndividualMath indiv4 = new IndividualMath( new
		 * HashMap<String, Integer>(), new HashMap<String, String>(), 0, 0,
		 * config, prototypes.get("Test math 4")); showPanelIndiv(indiv4,
		 * "Prototype 4"); IndividualMath indiv5 = new IndividualMath( new
		 * HashMap<String, Integer>(), new HashMap<String, String>(), 0, 0,
		 * config, prototypes.get("Test math 5")); showPanelIndiv(indiv5,
		 * "Prototype 5");
		 */
	}

	public static void printNathsData() {

	}

	public static void sortNathsData() {
		double[] tmp = new double[seqK.length];
		System.arraycopy(seqK, 0, tmp, 0, tmp.length);
		int[] oldPos = new int[seqStr.length];
		for (int i = 0; i < oldPos.length; i++) {
			int pos = 0;
			for (int j = 0; j < tmp.length; j++) {
				if (tmp[pos] > tmp[j]) {
					pos = j;
				}
			}
			oldPos[i] = pos;
			tmp[pos] = Double.MAX_VALUE;
		}
		for (int i = 0; i < oldPos.length; i++) {
			System.out.println(oldPos[i] + " " + seqK[oldPos[i]] + " "
					+ seqStr[oldPos[i]]);
		}
		System.out.println("Copy from here to end");
		System.out.print("public static double[] seqK = new double[] {"
				+ seqK[oldPos[0]]);
		for (int i = 1; i < oldPos.length; i++) {
			System.out.print(", " + seqK[oldPos[i]]);
		}
		System.out.println(" };");
		System.out.print("public static String[] seqStr = new String[] {"
				+ "\"" + seqStr[oldPos[0]] + "\"");
		for (int i = 1; i < oldPos.length; i++) {
			System.out.print(", \"" + seqStr[oldPos[i]] + "\"");
		}
		System.out.println(" };");
		System.out
				.println("public static double[][] inhibKm = new double[][] {");
		for (int i = 0; i < inhibKm.length; i++) {
			if (i > 0) {
				System.out.println(", ");
			}
			System.out.print("{");
			for (int j = 0; j < inhibKm[i].length; j++) {
				if (j > 0) {
					System.out.print(", ");
				}
				System.out.print(inhibKm[oldPos[i]][oldPos[j]]);
			}
			System.out.print("}");
		}
		System.out.println("};");
	}

	public static void showPanelIndiv(IndividualMath indiv, String title) {
		MathFitness fitness = new MathFitness();
		indiv.fitnessResult = fitness.evaluateFitness(indiv.getOligoModel());
		JFrame frame = new JFrame(title);
		frame.setSize(1024, 768);
		frame.setVisible(true);
		JPanel panelIndiv = new JPanel();
		frame.add(panelIndiv, BorderLayout.CENTER);
		panelIndiv.setLayout(new BorderLayout(0, 0));
		GraphDisplayer bestIndividuals = new GraphDisplayer(
				panelIndiv.getSize().width, panelIndiv.getSize().height);
		panelIndiv.add(bestIndividuals, BorderLayout.CENTER);
		bestIndividuals.addIndividual(indiv);
		panelIndiv.revalidate();
	}
}
